/*                   _   _ _ __                               *\
**     ________ ___ | | | | '_ \   scaup - Scala up!          **
**    / __/ __// _ || | | | |_) |  (c) 2008, Normen Mueller   **
**  __\ \/ /__/ __ || |_| | .__/   http://kwarc.info.nmueller **
** /____/\___/_/ |_/ \__,_|_|                                 **
**                                                            **
\*                                                            */
  
// $Id: CommandLine.scala 9 2008-05-24 12:12:30Z normen.mueller $

package scaup.io

/** A class representing command line info */
class CommandLine(cmdName: String, arguments: List[String], val settings: Settings, error: String => Unit) {

  /** All files to process */
  def files: List[String] = fs.reverse
  
  /** A message explaining usage and options */
  def usageMsg: String = {
    settings.allSettings.filter(_.isStandard)
      .map(setting => format(setting.helpSyntax) + "  " + setting.helpDescription)
      .mkString("Usage: " + cmdName + " <options> <source files>\n" +
                "where possible standard options include:\n  ",
                "\n  ",
                "\n")
  }
  
  /** Whether the command was processed okay */
  var ok = true
  
  /** Process the arguments and update the settings accordingly. This method is called only once, during initialization. */
  protected def processArguments() {
    // initialization
    var args = arguments

    while (!args.isEmpty && ok) {
      if (args.head startsWith "-") {
        val args0 = args
        for (setting <- settings.allSettings)
          if (args eq args0)
            args = setting.tryToSet(args)
          if (args eq args0) {
            error("bad option: '" + args.head + "'")
            ok = false
          }
        } else {
          fs = args.head :: fs
          args = args.tail
        } 
    }
    ok &&= settings.checkDependencies
  }
  
  private var fs: List[String] = List()

  private val helpSyntaxColumnWidth: Int = Iterable.max(settings.allSettings map (_.helpSyntax.length)) 

  private def format(s: String): String = {
    val buf = new StringBuilder(s)
    var i = s.length
    while (i < helpSyntaxColumnWidth) { buf.append(' '); i += 1 }
    buf.toString()
  } 

  processArguments()
}
